/*
 * Copyright (C) 拾光分享网
 * All rights reserved, Designed By www.hiai.top.
 * Email：goodsking@163.com.
 */
package top.hiai.my.index;

import com.jfinal.kit.LogKit;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.*;
import top.hiai.common.account.UserService;
import top.hiai.common.model.Article;
import top.hiai.common.model.Download;
import top.hiai.common.model.Message;

import java.sql.SQLException;
import java.util.Date;

/**
 * @Author www.hiai.top
 * @Email goodsking@163.com
 * @Message 更多资源尽在www.hiai.top
 * @Introduction 类的介绍
 */

public class IndexMyService {

    private Message messageDao = new Message().dao();
    private Article articleDao = new Article().dao();
    private Download downloadDao = new Download().dao();

    /**
     * 添加关注的好友
     *
     * @param accountId 登录用户的ID
     * @param uid       要关注的用户ID
     * @return
     */
    public Ret myFriendAdd(int accountId, int uid) {
        if (accountId == uid) {
            return Ret.fail().set("msg", "不能添加自己为好友");
        }
        Record friend = new Record().set("fids", accountId).set("uid", uid).set("addtime", new Date());
        try {
            Db.save("bbs_friend", "fids,uid", friend);
            // TODO 改为更细粒度的缓存以后该这样用： NewsFeedService.me.clearCache(accountId); 即只删除指令用户的缓存
            // TODO 备忘：由于 news feed 列表与好友有关：显示自己与好友的 news feed，所以要清掉相关 newsfeed
            //NewsFeedService.me.clearCache();
            //RemindService.me.createRemindOfNewFans(friendId);   // 向增加粉丝的用户发送提醒
            return Ret.ok();
        } catch (ActiveRecordException e) {
            // 快速多次点击关注按钮时，插入重复值时会抛异常，返回成功
            if (e.getCause() instanceof com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException) {
                return Ret.ok();
            }
            return Ret.fail().set("msg", "添加关注失败");
        }
    }

    /**
     * 删除关注的好友
     *
     * @param accountId 登录用户的ID
     * @param uid       好友ID
     * @return
     */
    public Ret myFriendDel(int accountId, int uid) {
        if (accountId == uid) {
            return Ret.fail().set("msg", "不能删除自己好友");
        }
        int result = Db.update(" delete from bbs_friend where fids=? and uid=? ", accountId, uid);
        if (result > 0) {
            return Ret.ok();
        } else {
            return Ret.fail().set("msg", "删除失败！");
        }
        // TODO 改为更细粒度的缓存以后该这样用： NewsFeedService.me.clearCache(accountId); 即只删除指令用户的缓存
        // TODO 备忘：由于 news feed 列表与好友有关：显示自己与好友的 news feed，所以要清掉相关 newsfeed
        //NewsFeedService.me.clearCache();
    }

    /**
     * 添加发送的私信
     *
     * @param accountId //谁发送的
     * @param friendId  //发给谁
     * @param content   //发送的内容
     * @return 后期可以加入一个redme表，用户接受用户消息提醒
     */
    public Ret sendUserMessageAdd(int accountId, int friendId, String content) {
        if (accountId == friendId) {
            return Ret.fail().set("msg", "您不能给自己发送私信。");
        }
        Message message1 = new Message();
        message1.setUserId(friendId);
        message1.setFriendId(accountId);
        message1.setSendId(accountId);
        message1.setUid(friendId);
        message1.setType(Message.TYPE_NORMAL);
        message1.setContent(content);
        message1.setAddtime(new Date());

        Message message2 = new Message();
        message2.setUserId(accountId);
        message2.setFriendId(friendId);
        message2.setSendId(accountId);
        message2.setUid(friendId);
        message2.setType(Message.TYPE_NORMAL);
        message2.setContent(content);
        message2.setAddtime(new Date());

        if (message1.save() && message2.save()) {
            return Ret.ok("msg", "发送成功。");
        } else {
            return Ret.fail().set("msg", "发送失败，请告知管理员");
        }
    }

    /**
     * 返回该用户的所有私信，分页显示
     *
     * @param pageNumber
     * @param pageSize
     * @param uid
     * @return
     */
    public Page<Message> userMessageListPage(int pageNumber, int pageSize, int uid) {
        //select f.mid,u.nickName,t.msgCount,t.maxId from ( select max(mid) as maxId , count(uid) as msgCount from bbs_message where bbs_message.uid = 1 group by sendId ) as t inner join bbs_user as u ,bbs_message as f where u.uid=f.sendId and t.maxId = f.mid;
        //String select = "select u.uid,u.nickName,u.avatar,f.mid,f.sendId,f.content,f.addtime ,t.msgCount ,t.maxId ";
        //String from = " from ( select max(mid) as maxId , count(uid) as msgCount from bbs_message where bbs_message.uid = ? group by sendId ) as t inner join bbs_user as u,bbs_message as f where u.uid=f.sendId and t.maxId=f.mid order by f.addtime desc ";
        String select = "select u.uid,u.nickName,u.avatar,f.mid,f.friendId,f.content,f.addtime ,t.msgCount ,t.maxId ";
        String from = " from ( select max(mid) as maxId , count(mid) as msgCount from bbs_message where bbs_message.userId = ? group by friendId ) as t inner join bbs_user as u,bbs_message as f where u.uid=f.friendId and t.maxId=f.mid order by f.addtime desc ";

        Page<Message> messagePage = messageDao.paginate(pageNumber, pageSize, select, from, uid);
        return messagePage;
    }

    /**
     * 返回单个私信，私信对话,分页显示
     *
     * @param pageNum
     * @param accountId
     * @param friendId
     * @return
     */
    public Page<Message> userMessageDetailPage(int pageNum, int pageSize, int accountId, int friendId) {
        String select = "select f.mid,f.sendId,f.content,f.addtime,u.uid,u.nickName,u.avatar";
        String from = "from bbs_message as f , bbs_user as u where f.userId=? and f.friendId=? and f.sendId = u.uid order by f.addtime desc";
        //String from = "from bbs_message as f , bbs_user as u where f.uid=? and f.sendId=? and f.sendId = u.uid union all "
        //		+ " from bbs_message as f , bbs_user as u where f.uid=? and f.sendId=? and f.sendId = u.uid ";

        Page<Message> messagePage = messageDao.paginate(pageNum, pageSize, select, from, accountId, friendId);
        //UserService.me.join("sendId", messagePage.getList(), "nickName", "avatar");
        return messagePage;
    }

    /**
     * 回复某个用户的发送普通私信
     *
     * @param sender
     * @param receiver
     * @param content
     * @return
     */
    public Ret userMessageReply(int sender, int receiver, String content) {
        return userMessageReply(sender, receiver, Message.TYPE_NORMAL, content);
    }

    /**
     * 回复用户的私信
     *
     * @param sender   发送人
     * @param receiver 接受人
     * @param type     私信的类型
     * @param content  私信的内容
     * @return
     */
    private Ret userMessageReply(final int sender, final int receiver, final int type, final String content) {

        if (sender == receiver) {
            return Ret.fail().set("msg", "不能给自己发送私信");
        }

        if (type < Message.TYPE_NORMAL || type > Message.TYPE_SYSTEM) {
            throw new IllegalArgumentException("type 值不正确");
        }
        final Ret ret = Ret.create();
        final Message m1 = new Message();

        boolean isOk = Db.tx(new IAtom() {
            public boolean run() throws SQLException {
                m1.setUserId(receiver);
                m1.setFriendId(sender);
                m1.setSendId(sender);
                m1.setUid(receiver);
                m1.setType(type);
                m1.setContent(content);
                m1.setAddtime(new Date());

                //用户新消息提醒
                //ReferMeKit.buildAtMeLink(m1);   // 转换 @提到我
                //RemindService.me.createRemindOfMessage(receiver);   // 向收信人发一个提醒

                // 系统消息，只保留收信人的信息，不创建发件人的信息
                if (type == Message.TYPE_SYSTEM) {
                    ret.set("message", m1);
                    return m1.save();
                }
                // 如果是"非系统消息" 同时为发信人保存一条信息，例如：点赞功能发送的是系统消息，但发信人是点赞的人
                Message m2 = new Message();
                m2.setUserId(sender);
                m2.setFriendId(receiver);
                m2.setSendId(sender);
                m2.setUid(receiver);
                m2.setType(type);
                m2.setContent(content);
                m2.setAddtime(new Date());
                //ReferMeKit.buildAtMeLink(m2);   // 转换 @提到我
                ret.set("message", m2);
                return m1.save() && m2.save();
            }
        });

        if (isOk) {
            return ret.setOk();
        } else {
            String msg = "消息发送失败，请告知管理员";
            LogKit.error(msg);
            return Ret.fail().set("msg", msg);
        }
    }

    /**
     * 删除某一条私信
     * message.user 字段表示 message 记录的主人，message 只有主人才可以删除
     */
    public Ret deleteByMessageId(int accountId, int messageId) {
        Db.update("delete from bbs_message where userId=? and mid=?", accountId, messageId);
        return Ret.ok();
    }

    /**
     * 删除某一个用户的所有私信往来
     * message.user 字段表示 message 记录的主人，message 只有主人才可以删除
     */
    public Ret deleteByFriendIdAll(int accountId, int friendId) {
        Db.update("delete from bbs_message where userId=? and friendId=?", accountId, friendId);
        return Ret.ok();
    }

    /**
     * 显示该用户关注的好友的动态消息
     *
     * @param pageNum
     * @param pageSize
     * @param uid
     * @return
     */
    public Page<Article> myFriendDynamicPage(int pageNum, int pageSize, int uid) {
        //select a.title from ( select max(u.uid) as maxId from bbs_friend as f ,bbs_user as u where f.uid=u.uid and f.fids=1 group by u.uid ) as t inner join bbs_article as a where a.uid=t.maxId;
        String select = " select a.aid,a.title,a.addtime,a.views,a.favoriteCount,t.maxId";
        String from = " from ( select max(u.uid) as maxId from bbs_friend as f ,bbs_user as u where f.uid=u.uid and f.fids=? group by u.uid ) as t inner join bbs_article as a where a.uid=t.maxId and a.status=1 ORDER BY a.addtime desc ";
        Page<Article> articlepage = articleDao.paginate(pageNum, pageSize, select, from, uid);
        UserService.me.join("maxId", articlepage.getList(), "uid", "nickName", "avatar", "is_auth");
        return articlepage;
    }

    /**
     * 根据用户登录的ID遍历该用户已经下载的文章资源
     *
     * @param pageNumber
     * @param pageSize
     * @return
     */
    public Page<Download> paginateGetUserXia(int pageNumber, int pageSize, int uid) {
        String select = " select b.aid,b.title,a.xid ,a.download_date ";
        String from = " from bbs_download a,bbs_article b where b.aid=a.article_id and a.user_id= " + uid + " order by a.download_date DESC ";
        return downloadDao.paginate(pageNumber, pageSize, select, from);
    }
}